package cn.paul.wechatshop.service.impl;

import cn.paul.wechatshop.common.Const;
import cn.paul.wechatshop.common.ServerResponse;
import cn.paul.wechatshop.dao.OrderDetailDao;
import cn.paul.wechatshop.dao.OrderMasterDao;
import cn.paul.wechatshop.dao.ProductInfoDao;
import cn.paul.wechatshop.dto.CartDTO;
import cn.paul.wechatshop.dto.OrderDTO;
import cn.paul.wechatshop.entity.OrderDetail;
import cn.paul.wechatshop.entity.OrderMaster;
import cn.paul.wechatshop.entity.ProductInfo;
import cn.paul.wechatshop.exception.WechatshopException;
import cn.paul.wechatshop.form.OrderForm;
import cn.paul.wechatshop.service.IOrderMasterService;
import cn.paul.wechatshop.service.IProductInfoService;
import cn.paul.wechatshop.utils.BigDecimalUtil;
import cn.paul.wechatshop.utils.KeyUtil;
import com.google.common.collect.Lists;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 徐凌峰
 * @date 2017/12/12 0012
 */
@Service
@Slf4j
public class OrderMasterServiceImpl implements IOrderMasterService {


    @Autowired
    private OrderMasterDao orderMasterDao;
    @Autowired
    private ProductInfoDao productInfoDao;
    @Autowired
    private OrderDetailDao orderDetailDao;
    @Autowired
    private IProductInfoService iProductInfoService;


    @Override
    @Transactional
    public String create(OrderForm orderForm) {
        OrderDTO orderDTO = convert(orderForm);
        String orderId = KeyUtil.getUniqueKey();
        //1.查询商品的库存和价格
        BigDecimal orderAmount = new BigDecimal("0");
        for (OrderDetail orderDetail : orderDTO.getOrderDetailList()) {
            ProductInfo productInfo = productInfoDao.findOne(orderDetail.getProductId());
            if (productInfo == null) {
                throw new WechatshopException(Const.ResultEnum.PRODUCT_NOT_EXITS);
            }
            //2.计算总价
            orderAmount = BigDecimalUtil.add(orderAmount.doubleValue(),
                    BigDecimalUtil.mul(productInfo.getProductPrice().doubleValue(),
                            orderDetail.getProductQuantity().doubleValue()).doubleValue());
            //3.写入订单详情数据库(orderMaster和orderDetail表)
            orderDetail.setOrderId(orderId);
            orderDetail.setDetailId(KeyUtil.getUniqueKey());
            BeanUtils.copyProperties(productInfo, orderDetail);
            orderDetailDao.save(orderDetail);
            OrderMaster orderMaster = new OrderMaster();
            orderDTO.setOrderId(orderId);
            BeanUtils.copyProperties(orderDTO, orderMaster);
            orderMaster.setOrderStatus(Const.OrderStatusEnum.NO_PAY.getCode());
            orderMaster.setOrderAmount(orderAmount);
            orderMasterDao.save(orderMaster);

//            CartDTO cartDTO  =new CartDTO(productInfo.getProductId(),orderDetail.getProductQuantity());
//            cartDTOList.add(cartDTO);
        }

        //4.扣除库存
        List<CartDTO> cartDTOList =
                orderDTO.getOrderDetailList().
                        stream().map
                        (e -> new CartDTO(e.getProductId(), e.getProductQuantity())).collect(Collectors.toList());
        iProductInfoService.decreaseStock(cartDTOList);
        return orderDTO.getOrderId();
    }

    @Override
    public ServerResponse<OrderDTO> findOne(String orderId) {
        OrderMaster orderMaster = orderMasterDao.findOne(orderId);
        if (orderMaster == null) {
            throw new WechatshopException(Const.ResultEnum.ORDER_NOT_EXISTS);
        }

        List<OrderDetail> orderDetailList = orderDetailDao.findByOrderId(orderId);
        if (CollectionUtils.isEmpty(orderDetailList)) {
            throw new WechatshopException(Const.ResultEnum.ORDER_DETAIL_NOT_EXISTS);
        }
        OrderDTO orderDTO = convert(orderMaster);
        orderDTO.setOrderDetailList(orderDetailList);
        return ServerResponse.createBySuccess(orderDTO);
    }

    @Override
    public ServerResponse findList(String buyerOpenid, Pageable pageable) {
        Page<OrderMaster> orderMasterPage = orderMasterDao.findByBuyerOpenid(buyerOpenid, pageable);
        List<OrderMaster> orderMasterList = orderMasterPage.getContent();
        List<OrderDTO> orderDTOList = convert(orderMasterList);
        return ServerResponse.createBySuccess("成功",new PageImpl<>(orderDTOList).getContent());
    }

    @Override
    @Transactional
    public ServerResponse<OrderDTO> finish(String orderId) {
        OrderMaster orderMaster = orderMasterDao.findOne(orderId);
        if (orderMaster == null) {
            throw new WechatshopException(Const.ResultEnum.ORDER_NOT_EXISTS);
        }
        //判断订单状态
        if (orderMaster.getOrderStatus() != Const.OrderStatusEnum.PAID.getCode()) {
            log.error("完结订单,订单状态不正确.订单Id={}", orderMaster.getOrderId());
            throw new WechatshopException(Const.ResultEnum.ORDER_STATUS_ERROR);
        }
        //修改订单状态
        orderMaster.setOrderStatus(Const.OrderStatusEnum.ORDER_SUCCESS.getCode());
        OrderMaster result = orderMasterDao.save(orderMaster);
        if (result == null) {
            log.error("[完结订单]更新失败,orderMaster={}", orderMaster);
            throw new WechatshopException(Const.ResultEnum.ORDER_UPDATE_FAILED);
        }

        OrderDTO orderDTO = convert(orderMaster);
        return ServerResponse.createBySuccess(orderDTO);
    }

    @Override
    @Transactional
    public ServerResponse<OrderDTO> cancel(String orderId) {
        OrderMaster orderMaster = orderMasterDao.findOne(orderId);
        if (orderMaster == null) {
            throw new WechatshopException(Const.ResultEnum.ORDER_NOT_EXISTS);
        }

        //判断订单状态
        if (orderMaster.getOrderStatus() != Const.OrderStatusEnum.NO_PAY.getCode() | orderMaster.getOrderStatus() != Const.OrderStatusEnum.PAID.getCode()) {
            log.error("取消订单,订单状态不正确.订单Id={}", orderMaster.getOrderId());
            throw new WechatshopException(Const.ResultEnum.ORDER_STATUS_ERROR);
        }

        //修改订单状态
        orderMaster.setOrderStatus(Const.OrderStatusEnum.CANCELED.getCode());
        OrderMaster result = orderMasterDao.save(orderMaster);
        if (result == null) {
            log.error("[取消订单]更新失败,orderMaster={}", orderMaster);
            throw new WechatshopException(Const.ResultEnum.ORDER_UPDATE_FAILED);
        }

        //将库存返回
        List<CartDTO> cartDTOList = orderDetailDao.findByOrderId(orderId).stream()
                .map(e -> new CartDTO(e.getProductId(), e.getProductQuantity())).collect(Collectors.toList());
        iProductInfoService.increaseStock(cartDTOList);
        //如果已经支付就退款,执行退款操作
        if (orderMaster.getOrderStatus() == Const.OrderStatusEnum.PAID.getCode()) {
            //todo 执行退款操作
        }
        OrderDTO orderDTO = convert(orderMaster);
        return ServerResponse.createBySuccess(orderDTO);
    }

    @Override
    @Transactional
    public ServerResponse<OrderDTO> pay(String orderId) {
        OrderMaster orderMaster = orderMasterDao.findOne(orderId);
        if (orderMaster == null) {
            throw new WechatshopException(Const.ResultEnum.ORDER_NOT_EXISTS);
        }
        //判断订单状态
        if (orderMaster.getOrderStatus() != Const.OrderStatusEnum.NO_PAY.getCode()) {
            log.error("支付订单,订单状态不正确.订单Id={}", orderMaster.getOrderId());
            throw new WechatshopException(Const.ResultEnum.ORDER_STATUS_ERROR);
        }

        //修改订单状态
        orderMaster.setOrderStatus(Const.OrderStatusEnum.NO_PAY.getCode());
        OrderMaster result = orderMasterDao.save(orderMaster);
        if (result == null) {
            log.error("[支付订单]更新失败,orderMaster={}", orderMaster);
            throw new WechatshopException(Const.ResultEnum.ORDER_UPDATE_FAILED);
        }

        //todo 执行支付操作


        OrderDTO orderDTO = convert(orderMaster);
        return ServerResponse.createBySuccess(orderDTO);
    }

    /**
     * 类型转换器
     *
     * @param orderMaster
     * @return orderDTO
     */
    public static OrderDTO convert(OrderMaster orderMaster) {
        OrderDTO orderDTO = new OrderDTO();
        BeanUtils.copyProperties(orderMaster, orderDTO);
        return orderDTO;
    }

    private static OrderDTO convert(OrderForm orderForm) {
        OrderDTO orderDTO = new OrderDTO();
        orderDTO.setBuyerAddress(orderForm.getBuyerAddress());
        orderDTO.setBuyerName(orderForm.getBuyerName());
        orderDTO.setBuyerOpenid(orderForm.getBuyerOpenid());
        orderDTO.setBuyerPhone(orderForm.getBuyerPhone());

        Gson gson = new Gson();
        List<OrderDetail> orderDetailList = Lists.newArrayList();
        try {
            orderDetailList = gson.fromJson(orderForm.getItems(), new TypeToken<List<OrderDetail>>() {
            }.getType());
            if(CollectionUtils.isEmpty(orderDetailList)){
                log.error("[创建订单]购物车不能为空");
                throw new WechatshopException(Const.ResultEnum.CART_EMPTY);
            }
            orderDTO.setOrderDetailList(orderDetailList);

        } catch (Exception e) {
            log.error("[对象转换]错误,items={}", orderForm.getItems());
            throw new WechatshopException(Const.ResultEnum.PARAM_ERROR);
        }
        return orderDTO;
    }

    private static List<OrderDTO> convert(List<OrderMaster> orderMasterList) {
        return orderMasterList.stream().map(e -> convert(e)).collect(Collectors.toList());
    }


}
